<template>
    <div class="editor-container" v-bind="$attrs">
        <el-upload
            :action="uploadUrl"
            :before-upload="handleBeforeUpload"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            name="file"
            :show-file-list="false"
            :headers="headers"
            class="editor-img-uploader"
            v-if="props.type === 'url'"
        >
            <i ref="imageUploadRef" class="Plus editor-img-uploader"></i>
        </el-upload>
        <QuillEditor
            theme="snow"
            :content="model"
            contentType="html"
            ref="myQuillEditor"
            @update:content="update"
            @textChange="textChange"
            :options="options"
        />
    </div>
</template>
<script setup lang="ts">
import { ref, watch, reactive, toRaw, onMounted } from "vue";
import { SCMessage } from "@sribd/sc-ui";
import { QuillEditor, Quill } from "@vueup/vue-quill";
import MagicUrl from "quill-magic-url";
import Delta from "quill-delta";
import normalizeUrl, { Options as NormalizeUrlOptions } from "normalize-url";
import ResizeModule from "./ResizeModule";
import "./VideoBlot";
import { getToken } from "@/utils/auth";
import { validUrl } from "~/utils/urlReg";
import { useUserStore } from "@/store/user";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
const props = defineProps({
    modelValue: {
        type: String,
        default: "",
    },
    readOnly: {
        type: Boolean,
        default: false,
    },
    // 上传文件大小限制(MB)
    fileSize: {
        type: Number,
        default: 100,
    },
    /* 类型（base64格式、url格式） */
    type: {
        type: String,
        default: "url",
    },
});

const emits = defineEmits(["change", "update:modelValue", "getFileId"]);
const imageUrlRef = ref();
const imageUploadRef = ref();
const model = ref(props.modelValue);
const myQuillEditor = ref();
watch(
    () => props.modelValue,
    (val: any) => {
        if (val instanceof Event) {
            return;
        }
        model.value = val;
        if (!val) {
            myQuillEditor.value.setHTML("");
        }
    },
);
const update = (content: string) => {
    emits("update:modelValue", content);
    emits("change", content);
};
const uploadUrl = import.meta.env.VITE_UPLOAD_URL;
const headers = reactive({
    Authorization: getToken(),
});

Quill.register("modules/magicUrl", MagicUrl);
Quill.register("modules/resize", ResizeModule);
// 1. 自定义字体大小白名单
const Size = Quill.import("attributors/style/size");
Size.whitelist = ["16px"]; // 只允许 16px
Quill.register(Size, true);
const options = reactive({
    theme: "snow",
    debug: "warn",
    modules: {
        // 工具栏配置
        toolbar: {
            container: [
                ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
                ["blockquote", "code-block"], // 引用  代码块
                [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
                [{ indent: "-1" }, { indent: "+1" }], // 缩进
                // [{ size: ['small', false, 'large', 'huge'] }], // 字体大小
                [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
                [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
                [{ align: [] }], // 对齐方式
                ["clean"], // 清除文本格式
                ["link", "image"], // 链接、图片
                ["video"], // 显示视频按钮
            ],
            handlers: {
                // 重写图片上传事件
                image: function (value) {
                    if (value) {
                        //调用图片上传
                        imageUploadRef.value?.click();
                    }
                    // else {
                    //     Quill?.format("image", true);
                    // }
                },
                video: function () {
                    const input = document.createElement("input");
                    input.type = "file";
                    input.accept = "video/*";
                    input.addEventListener("change", async (event) => {
                        const file = (event.target as HTMLInputElement).files?.[0];
                        if (file) {
                            // 模拟上传视频到服务器
                            const videoUrl = await uploadVideo(file);
                            let quill = toRaw(myQuillEditor.value).getQuill();
                            // 插入图片，res为服务器返回的图片链接地址
                            const range = quill.getSelection();
                            quill.insertEmbed(range?.index || 0, "video", videoUrl);
                            quill.setSelection(length + 1);
                        }
                    });
                    input.click();
                },
            },
        },
        magicUrl: true,
    },
    placeholder: "请输入内容",
    readOnly: props.readOnly,
});

// 3. 强制字体大小逻辑
const content = ref("");
const handleChange = () => {
    const editor = document.querySelector(".ql-editor");
    if (editor) {
        editor.style.fontSize = "16px";
    }
};

const uploadVideo = async (file: File) => {
    // 这里可以实现具体的视频上传逻辑，例如使用 fetch 或 axios 发送请求
    // 以下是一个简单的示例，返回一个模拟的视频 URL
    return new Promise<string>((resolve) => {
        setTimeout(() => {
            resolve("https://example.com/video.mp4");
        }, 100);
    });
};

// const uploadVideo = async (file: File) => {
//     const formData = new FormData();
//     formData.append("video", file);

//     try {
//         const response = await axios.post("/api/upload-video", formData, {
//             headers: {
//                 "Content-Type": "multipart/form-data",
//             },
//         });
//         return response.data.videoUrl;
//     } catch (error) {
//         console.error("视频上传失败:", error);
//         return "";
//     }
// };

// function uploadVideo() {
//     const file = this.input.files[0];
//     if (!file) return;

//     // 上传到服务器（示例用伪代码）
//     const formData = new FormData();
//     formData.append('video', file);

//     // 模拟上传请求
//     fetch('https://your-api.com/upload', {
//       method: 'POST',
//       body: formData
//     })
//     .then(res => res.json())
//     .then(data => {
//       // 插入视频到编辑器
//       const range = this.quill.getSelection();
//       this.quill.insertEmbed(range.index, 'video', data.url);
//     })
//     .catch(error => {
//       console.error('Upload failed:', error);
//     });
//   }
defineExpose({
    getImageUrl: () => {
        return imageUrlRef.value;
    },
});
// 上传前校检格式和大小
function handleBeforeUpload(file) {
    const type = [
        "image/jpeg",
        "image/jpg",
        "image/png",
        "image/svg",
        "image/apng",
        "image/avif",
        "image/bmp",
        "image/gif",
        "image/x-icon",
        "image/svg+xml",
        "image/tiff",
        "image/webp",
    ];
    const isJPG = type.includes(file.type);
    //检验文件格式
    if (!isJPG) {
        SCMessage({ message: `图片格式错误!`, type: "error" });
        return false;
    }
    // 校检文件大小
    if (props.fileSize) {
        const isLt = file.size / 1024 / 1024 < props.fileSize;
        if (!isLt) {
            SCMessage({ message: `上传文件大小不能超过 ${props.fileSize} MB!`, type: "error" });
            return false;
        }
    }
    return true;
}
// 上传成功处理
function handleUploadSuccess(res, file) {
    console.log(file);
    // 如果上传成功
    if (res.code == 0) {
        // 获取富文本实例
        let quill = toRaw(myQuillEditor.value).getQuill();
        // 获取光标位置
        let length = quill.selection.savedRange.index;
        // 插入图片，res为服务器返回的图片链接地址
        let imageUrl = res.data.attachmentUrl;
        imageUrlRef.value = imageUrl;
        quill.insertEmbed(length, "image", imageUrl);
        // 调整光标到最后
        quill.setSelection(length + 1);
        emits("getFileId", res.fileId);
    } else {
        SCMessage({ message: "图片插入失败", type: "error" });
    }
}
// 上传失败处理
function handleUploadError(e) {
    SCMessage({ message: "图片插入失败", type: "error" });
}
const textChange = function ({ delta, oldContents, source }) {
    const quill = myQuillEditor.value?.getQuill();
    let hasChange = false;
    delta.ops.forEach((opsItem) => {
        const attributes = opsItem.attributes;
        if (delta && attributes && attributes.link) {
            const link = attributes.link;
            if (!link.includes("http")) {
                attributes.link = normalizeUrl(link);
                hasChange = true;
            }
        }
        return {
            ...opsItem,
            attributes,
        };
    });
    const editor = document.querySelector(".ql-editor");
    if (editor) {
        editor.style.fontSize = "16px";
    }
    // if (hasChange) {
    //     quill && quill.updateContents(delta);
    // }
};
onMounted(() => {
    // 注入 CSS 样式
    const style = document.createElement("style");
    style.textContent = `
    .ql-editor video {
      max-width: 100%;
      position: relative;
      transition: all 0.3s;
    }
    .ql-resize-handle {
      z-index: 9999;
    }
  `;
    document.head.appendChild(style);
});
</script>
<style lang="scss" scoped>
.editor-container {
    display: inline-block;
    width: 100%;
}
</style>
<style>
.editor,
.ql-toolbar {
    white-space: pre-wrap !important;
    line-height: normal !important;
}

.editor-img-uploader {
    display: none;
}

.ql-editor {
    min-height: 300px;
}

.ql-snow .ql-tooltip[data-mode="link"]::before {
    content: "请输入链接地址:";
}

.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
    border-right: 0px;
    content: "保存";
    padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
    content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
    content: "14px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
    content: "10px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
    content: "18px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
    content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
    content: "文本";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
    content: "标题1";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
    content: "标题2";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
    content: "标题3";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
    content: "标题4";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
    content: "标题5";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
    content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
    content: "标准字体";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
    content: "衬线字体";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
    content: "等宽字体";
}
</style>
